package cn.jpanda.elastic.job.autoconfigure.factory;

import org.springframework.boot.env.PropertySourceLoader;
import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.support.DefaultPropertySourceFactory;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.List;

/**
 * 自定义Yaml文件处理
 *
 * @author Hanqi <jpanda@aliyun.com>
 * @since 2018/9/25 19:02
 */
public class YamlPropertySourceFactory extends DefaultPropertySourceFactory {
    /**
     * Create a {@link PropertySource} that wraps the given resource.
     *
     * @param name     the name of the property source
     * @param resource the resource (potentially encoded) to wrap
     * @return the new {@link PropertySource} (never {@code null})
     * @throws IOException if resource resolution failed
     */
    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
        return loadResource(getResourceLoad(), name, resource);
    }

    /**
     * 获取PropertySource加载器
     *
     * @return PropertySource加载器
     */
    private YamlPropertySourceLoader getResourceLoad() {
        return new YamlPropertySourceLoader();
    }

    /**
     * 记载资源，并返回
     *
     * @param loader   PropertySource加载器
     * @param name     源名称
     * @param resource 资源
     */
    private PropertySource loadResource(PropertySourceLoader loader, String name, EncodedResource resource) throws IOException {

        List<PropertySource<?>> propertySources = loader.load(getSourceName(name, resource), resource.getResource());

        return CollectionUtils.isEmpty(propertySources) ? null : propertySources.get(0);
    }

    /**
     * 获取资源名称
     *
     * @param name     资源名称
     * @param resource 资源
     * @return 资源名称
     */
    private String getSourceName(String name, EncodedResource resource) {
        return StringUtils.hasText(name) ? name : resource.getResource().getFilename();

    }
}
